﻿using App_1.Contracts;
using App_1.Dtos;
using App_1.Entites;
using App_1.RequestFeatures;
using App_1.ResponseType.DataShaping;
using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace App_1.Controllers
{
    [Route("api/player")]
    [ApiController]
    public class PlayerController(IRepositoryWrapper repository,
           IMapper mapper, ILogger<PlayerController> logger) : ControllerBase
    {
        [Authorize]
        [HttpGet]
        public IActionResult GetPlayers([FromQuery] PlayerParameter parameter)
        {
            if (!parameter.ValidDateCreatedRange)
            {
                return BadRequest("开始日期不能大于结束日期！");
            }

            try
            {
                var players = repository.Player.GetPlayers(parameter);
                Response.Headers.Append("X-Pagination", JsonConvert.SerializeObject(players.MetaData));
                var result = mapper
                    .Map<IEnumerable<PlayerDto>>(players)
                    .ShapeData(parameter.Fields);

                return Ok(result);
            }
            catch (Exception ex)
            {
                logger.LogError($"{ex.Message}");
                return StatusCode(500);
            }
        }

        [Authorize]
        [HttpGet("{id}", Name = "PlayerById")]
        public IActionResult GetPlayerById(Guid id)
        {
            try
            {
                var player = repository.Player.GetPlayerById(id);
                if (player is null)
                {
                    return NotFound();
                }

                var result = mapper.Map<PlayerDto>(player);
                return Ok(result);
            }
            catch (Exception ex)
            {
                logger.LogError($"{ex.Message}");
                return StatusCode(500);
            }
        }

        [Authorize]
        [HttpGet("{id}/character")]
        public IActionResult GetPlayerWithCharacters(Guid id)
        {
            try
            {
                var player = repository.Player.GetPlayerWithCharacters(id);
                if (player is null)
                {
                    return NotFound();
                }

                var result = mapper.Map<PlayerWithCharactersDto>(player);
                return Ok(result);
            }
            catch (Exception ex)
            {
                logger.LogError(ex.Message);
                return StatusCode(500);
            }
        }

        [Authorize]
        [HttpPost]
        public IActionResult CreatePlayer([FromBody] PlayerForCreationDto player)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest("无效的请求数据");
                }

                var playerEntity = mapper.Map<Player>(player);

                repository.Player.CreatePlayer(playerEntity);
                repository.SaveChangesAsync();

                var createdPlayer = mapper.Map<PlayerDto>(playerEntity);
                return CreatedAtRoute("PlayerById", new { id = createdPlayer.Id }, createdPlayer);
            }
            catch (Exception ex)
            {
                logger.LogError(ex.Message);
                return StatusCode(500);
            }
        }

        [Authorize]
        [HttpPut("{id}")]
        public IActionResult UpdatePlayer(Guid id, [FromBody] PlayerForUpdateDto player)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest("无效的请求对象");
                }

                var playerEntity = repository.Player.GetPlayerById(id);
                if (playerEntity is null)
                {
                    return NotFound("待修改的玩家不存在");
                }

                mapper.Map(player, playerEntity);

                repository.Player.UpdatePlayer(playerEntity);
                repository.SaveChangesAsync();

                return NoContent();
            }
            catch (Exception ex)
            {
                logger.LogError(ex.Message);
                return StatusCode(500);
            }
        }

        [Authorize]
        [HttpDelete("{id}")]
        public IActionResult DeletePlayer(Guid id)
        {
            try
            {
                var player = repository.Player.GetPlayerWithCharacters(id);
                if (player is null)
                {
                    return BadRequest("该玩家不存在");
                }

                if (player.characters.Any())
                {
                    return BadRequest("该玩家有关联人物角色，不能删除！");
                }

                repository.Player.DeletePlayer(player);
                repository.SaveChangesAsync();

                return NoContent();
            }
            catch (Exception ex)
            {
                logger.LogError(ex.Message);
                return StatusCode(500);
            }
        }
    }
}